package com.ruoyi.web.controller.tool;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import com.google.common.collect.Maps;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.worker.domain.AttendanceGroup;
import com.ruoyi.worker.domain.AttendanceInfo;
import com.ruoyi.worker.domain.ExcelToolDomain;
import com.ruoyi.worker.service.AttendanceGroupService;
import com.ruoyi.worker.service.ExcelService;
import org.apache.commons.compress.utils.Lists;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.util.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @ClassName ExcelController
 * @Description excel导入导出
 * @Author leizhang
 * Date 2021/9/3 10:39 下午
 * @Version 1.0
 **/
@RestController
@RequestMapping("/excelToolApi")
public class ExcelController extends BaseController {
    private static final String TITLE = "人员出勤明细";
    private static final Logger LOGGER = LoggerFactory.getLogger(ExcelController.class);

    @Autowired
    private RuoYiConfig ruoYiConfig;

    @Autowired
    private ExcelService excelService;

    @Autowired
    private AttendanceGroupService attendanceGroupService;

    @PostMapping("/importData")
    public AjaxResult excelToolExport(MultipartFile[] file) {
        List<ExcelToolDomain> inputList = Lists.newArrayList();
        if (null != file && file.length > 0) {
            for (MultipartFile multipartFile : file) {
                try {
                    List<ExcelToolDomain> ExcelToolDomains = baseImport(multipartFile.getInputStream(), 1, 1, false, ExcelToolDomain.class);
                    inputList.addAll(ExcelToolDomains);
                } catch (Exception e) {
                    LOGGER.error("导入数据错误:[{}]", e.getMessage(), e);
                    return AjaxResult.error();
                }
            }
        }
        if (inputList.size() > 0) {
            //导出数据处理
            List<List<ExcelToolDomain>> listOfList = Lists.newArrayList();
            inputList.stream().collect(Collectors.groupingBy(ExcelToolDomain::getIdCard, Collectors.toList()))
                    .forEach((idCard, list) -> {
                        listOfList.add(list);
                    });
            //分组导入的数据
            //  [[{"workerName":"","idCard":"","phone":""}],[{},{}]]
            //以班组的信息为准，获取渠道商中的渠道数据，将两个数据合并 每个list中存在两个数据
            List<ExcelToolDomain> orderList = Lists.newArrayList();
            for (List<ExcelToolDomain> ExcelToolDomains : listOfList) {
                //数据简单的异常处理
                if (0 == ExcelToolDomains.size()) {
                    ExcelToolDomain ExcelToolDomain = ExcelToolDomains.get(0);
                    ExcelToolDomain.setRemark("渠道商与班组长提供的信息不一致,请核对");
                    orderList.add(ExcelToolDomain);
                    continue;
                }
                if (ExcelToolDomains.size() > 2) {
                    ExcelToolDomain ExcelToolDomain = ExcelToolDomains.get(0);
                    ExcelToolDomain.setRemark("渠道商或班组长提供的信息重复,请核对");
                    orderList.add(ExcelToolDomain);
                    continue;
                }
                ExcelToolDomain ExcelToolDomain = ExcelToolDomains.get(0);
                if (StringUtils.isBlank(ExcelToolDomain.getCompanyName())) {
                    //ExcelToolDomain 是班组信息 将1 中的渠道商放入到0中
                    String companyName = ExcelToolDomains.get(1).getCompanyName();
                    ExcelToolDomain.setCompanyName(companyName);
                    orderList.add(ExcelToolDomain);
                } else {
                    //则说明0是渠道商 将0放入 1中
                    String companyName = ExcelToolDomain.getCompanyName();
                    ExcelToolDomains.get(1).setCompanyName(companyName);
                    orderList.add(ExcelToolDomains.get(1));
                }
            }
            //再次分组以渠道商商分组
            List<List<ExcelToolDomain>> companyOfList = Lists.newArrayList();
            orderList.stream().collect(Collectors.groupingBy(ExcelToolDomain::getCompanyName, Collectors.toList()))
                    .forEach((companyName, companyList) -> {
                        companyOfList.add(companyList);
                    });

            //最终结果数据集 companyOfList
            //导出多sheet excel
            List<Map<String, Object>> sheetsList = Lists.newArrayList();
            ExportParams deptExportParams = null;
            Map<String, Object> deptExportMap = null;
            for (List<ExcelToolDomain> ExcelToolDomains : companyOfList) {
                deptExportParams = new ExportParams();
                // 设置sheet得名称
                deptExportParams.setSheetName(ExcelToolDomains.get(0).getCompanyName());
                deptExportParams.setTitle(ExcelToolDomains.get(0).getCompanyName().concat(TITLE));
                short hight = 20;
                deptExportParams.setTitleHeight(hight);
                // 创建sheet1使用得map
                deptExportMap = Maps.newHashMap();
                // title的参数为ExportParams类型，目前仅仅在ExportParams中设置了sheetName
                deptExportMap.put("title", deptExportParams);
                // 模版导出对应得实体类型
                deptExportMap.put("entity", ExcelToolDomain.class);
                // sheet中要填充得数据
                deptExportMap.put("data", ExcelToolDomains);
                sheetsList.add(deptExportMap);
            }
            Workbook workBook = ExcelExportUtil.exportExcel(sheetsList, ExcelType.HSSF);
            String fileName = TITLE.concat("_") + new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()).toString() + ".xlsx";
            OutputStream out = null;
            try {
                out = new FileOutputStream(getAbsoluteFile(fileName));
                workBook.write(out);
                return AjaxResult.success(fileName);
            } catch (Exception e) {
                LOGGER.error("excel输出错误信息:[{}]", e.getCause(), e);
                AjaxResult.error();
            } finally {
                IOUtils.closeQuietly(workBook);
                IOUtils.closeQuietly(out);
            }
        }
        return AjaxResult.error();
    }

    private <T> List<T> baseImport(InputStream inputStream, Integer titleRows, Integer headerRows,
                                   boolean needVerify, Class<T> pojoClass) throws Exception {
        if (inputStream == null) {
            return null;
        } else {
            final ImportParams params = new ImportParams();
            params.setTitleRows(titleRows);
            params.setHeadRows(headerRows);
            params.setNeedVerify(true);
            params.setNeedSave(false);
            return ExcelImportUtil.importExcel(inputStream, pojoClass, params);
        }

    }

    public String getAbsoluteFile(String filename) {
        String downloadPath = ruoYiConfig.getDownloadPath() + filename;
        File desc = new File(downloadPath);
        if (!desc.getParentFile().exists()) {
            desc.getParentFile().mkdirs();
        }
        return downloadPath;
    }


    /**
     * @param file
     * @return com.ruoyi.common.core.domain.AjaxResult
     * @Description : 班组考勤信息导入
     * @Author : leizhang
     * @Date 5:12 下午 2021/9/5
     **/
    @PostMapping("/importDataGroup")
    public AjaxResult importDataGroup(MultipartFile file) {
        List<ExcelToolDomain> ExcelToolDomains = null;
        try {
            ExcelToolDomains = baseImport(file.getInputStream(), 1, 1, false, ExcelToolDomain.class);
        } catch (Exception e) {
            LOGGER.error("班组信息导入失败:[{}]", e.getMessage(), e);
        }
        if (null == ExcelToolDomains) {
            return AjaxResult.error("excel班组信息导入失败，信息为空");
        }
        List<List<ExcelToolDomain>> listOfList = Lists.newArrayList();
        ExcelToolDomains.stream().collect(Collectors.groupingBy(ExcelToolDomain::getIdCard, Collectors.toList()))
                .forEach((idCard, list) -> {
                    listOfList.add(list);
                });
        String errName = null;

        for (List<ExcelToolDomain> toolDomains : listOfList) {
            if (toolDomains.size() > 1) {
                errName = toolDomains.get(0).getWorkerName();
                break;
            }
        }
        if (StringUtils.isNotBlank(errName)) {
            return AjaxResult.error(errName.concat("信息重复,请核对"));
        }

        for (int i = 0; i < ExcelToolDomains.size(); i++) {
            if (null == ExcelToolDomains.get(i).getWorkerName()) {
                return AjaxResult.error("第" + (i + 3) + "行员工姓名为空,请核对");
            }
            if (null == ExcelToolDomains.get(i).getIdCard()) {
                return AjaxResult.error("第" + (i + 3) + "行员工身份证为空,请核对");
            }
            if (null == ExcelToolDomains.get(i).getGroupName()) {
                return AjaxResult.error("第" + (i + 3) + "行岗位为空,请核对");
            }
        }
        //查询是否导入过了
        AttendanceGroup a = new AttendanceGroup();
        a.setWorkTime(ExcelToolDomains.get(0).getWorkTime());
        AttendanceGroup resultAttendanceGroup = attendanceGroupService.countAttendanceGroup(a);
        if (resultAttendanceGroup != null) {
            int importNum = 0;
            if (resultAttendanceGroup.getImportNum() != null) {
                importNum = resultAttendanceGroup.getImportNum();
            }

            //删除
            attendanceGroupService.delALlAttendanceGroup(a);
            for (int i = 0; i < ExcelToolDomains.size(); i++) {
                ExcelToolDomain e = ExcelToolDomains.get(i);
                e.setImportNum(importNum + 1);
                if (Objects.equals(e.getTimeShiftName(), "白班")) {
                    e.setTimeShift(1);

                } else if (Objects.equals(e.getTimeShiftName(), "夜班")) {
                    e.setTimeShift(2);

                } else if (Objects.equals(e.getTimeShiftName(), "通班")) {
                    e.setTimeShift(2);

                } else {
                    e.setTimeShift(4);

                }
                if (Objects.equals(e.getGroupName(), "卸车岗")) {
                    e.setGroupCode("ZK001");
                } else if (Objects.equals(e.getGroupName(), "供包")) {
                    e.setGroupCode("GB");
                } else if (Objects.equals(e.getGroupName(), "小件集包")) {
                    e.setGroupCode("xjjb");
                } else if (Objects.equals(e.getGroupName(), "装车")) {
                    e.setGroupCode("ZC");
                } else if (Objects.equals(e.getGroupName(), "扫描")) {
                    e.setGroupCode("SM");
                } else if (Objects.equals(e.getGroupName(), "分剔(卸车站皮带)")) {
                    e.setGroupCode("ft");
                } else if (Objects.equals(e.getGroupName(), "分拣")) {
                    e.setGroupCode("fj");
                } else if (Objects.equals(e.getGroupName(), "小件开拆")) {
                    e.setGroupCode("xjkc");
                }


            }
        }
        excelService.saveWorkerGroupInfo(ExcelToolDomains);
        //获取渠道商考勤信息
        List<ExcelToolDomain> list = excelService.getAttendanceCompany(ExcelToolDomains.get(0));
        //对比
        int totalNum = 0;
        int normalNum = 0;
        int abnormalNum = 0;
        AttendanceInfo attendanceInfo = new AttendanceInfo();
        if (list == null || list.size() == 0) {
            //保存到汇总的考勤表
            totalNum = ExcelToolDomains.size();
            normalNum = totalNum;
            abnormalNum = 0;
            for (int i = 0; i < ExcelToolDomains.size(); i++) {
                //初始有差异
                ExcelToolDomains.get(i).setAttendanceFlag(0);
                ExcelToolDomains.get(i).setStatusFlag(0);
            }

            attendanceGroupService.delALlAttendanceSum(a);
            excelService.saveAttendanceInfo(ExcelToolDomains);
        } else {
            int lengthA = ExcelToolDomains.size();
            int lengthB = list.size();
            List<ExcelToolDomain> abnormalList = new ArrayList<>();
            List<ExcelToolDomain> normalList = new ArrayList<>();

            for (int i = 0; i < ExcelToolDomains.size(); i++) {
                ExcelToolDomain tempExcelToolDomainA = ExcelToolDomains.get(i);
                String idCard = tempExcelToolDomainA.getIdCard();
                int flag = 0;
                for (int j = 0; j < list.size(); j++) {
                    ExcelToolDomain tempExcelToolDomainB = list.get(j);

                    if (Objects.equals(idCard, tempExcelToolDomainB.getIdCard())) {
                        flag = 1;
                        tempExcelToolDomainA.setCompanyName(tempExcelToolDomainB.getCompanyName());
                        if (tempExcelToolDomainA.getCompanyName() == null) {
                            //未知
                            tempExcelToolDomainA.setStatusFlag(0);
                        } else {
                            tempExcelToolDomainA.setStatusFlag(1);
                        }
                        ExcelToolDomains.get(i).setCompanyName(list.get(j).getCompanyName());
                        if (!Objects.equals(tempExcelToolDomainA.getWorkerName(), tempExcelToolDomainB.getWorkerName())) {
                            tempExcelToolDomainA.setAttendanceFlag(0);
                        }
                        if (!Objects.equals(tempExcelToolDomainA.getGroupName(), tempExcelToolDomainB.getGroupName())) {
                            tempExcelToolDomainA.setAttendanceFlag(0);
                        }
                        if (!Objects.equals(tempExcelToolDomainA.getCompanyName(), tempExcelToolDomainB.getCompanyName())) {
                            tempExcelToolDomainA.setAttendanceFlag(0);
                        }
                        if (!Objects.equals(tempExcelToolDomainA.getTimeShiftName(), tempExcelToolDomainB.getTimeShiftName())) {
                            tempExcelToolDomainA.setAttendanceFlag(0);
                        }
                        if (tempExcelToolDomainA.getAttendanceFlag() == 0) {
                            abnormalList.add(tempExcelToolDomainA);
                        } else {
                            normalList.add(tempExcelToolDomainA);
                        }

                    }
                }
                //班组导入独有的数据
                if (flag == 0) {
                    tempExcelToolDomainA.setAttendanceFlag(0);
                    if (tempExcelToolDomainA.getCompanyName() == null) {
                        //未知
                        tempExcelToolDomainA.setStatusFlag(0);
                    } else {
                        tempExcelToolDomainA.setStatusFlag(1);
                    }
                    abnormalList.add(tempExcelToolDomainA);
                }
            }
            //渠道商独有的数据
            for (int i = 0; i < list.size(); i++) {
                ExcelToolDomain tempExcelToolDomainB = list.get(i);
                String idCard = tempExcelToolDomainB.getIdCard();
                int flag = 0;
                for (int j = 0; j < ExcelToolDomains.size(); j++) {

                    ExcelToolDomain tempExcelToolDomainA = ExcelToolDomains.get(j);
                    if (Objects.equals(idCard, tempExcelToolDomainB.getIdCard())) {
                        flag = 1;
                        break;
                    }
                }

                if (flag == 0) {
                    tempExcelToolDomainB.setAttendanceFlag(0);
                    if (tempExcelToolDomainB.getGroupName() == null) {
                        //未知
                        tempExcelToolDomainB.setStatusFlag(0);
                    } else {
                        tempExcelToolDomainB.setStatusFlag(1);
                    }
                    abnormalList.add(tempExcelToolDomainB);
                }
            }
            //保存到汇总的考勤表
            normalNum = normalList.size();
            abnormalNum = abnormalList.size();
            totalNum = normalNum + abnormalNum;
            abnormalList.addAll(normalList);
            attendanceGroupService.delALlAttendanceSum(a);
            excelService.saveAttendanceInfo(abnormalList);
        }
        attendanceGroupService.delALlAttendancestatistics(a);
        attendanceInfo.setStatus(0);
        attendanceInfo.setWorkTime(a.getWorkTime());
        attendanceInfo.setTotalNum(totalNum);
        attendanceInfo.setAbnormalNum(abnormalNum);
        attendanceInfo.setNormalNum(normalNum);
        String orderCode = DateUtils.parseDateToStr("yyyyMMdd", a.getWorkTime());
        orderCode = orderCode + "001";
        attendanceInfo.setOrderCode(orderCode);
        attendanceGroupService.addAttendanceStatistics(attendanceInfo);

        return AjaxResult.success();
    }


    /**
     * @param file
     * @return com.ruoyi.common.core.domain.AjaxResult
     * @Description : 渠道商考勤信息导入
     * @Author : leizhang
     * @Date 5:12 下午 2021/9/5
     **/
    @PostMapping("/importDataCompany")
    public AjaxResult importDataCompany(MultipartFile file) {
        List<ExcelToolDomain> excelToolDomains = null;
        try {
            excelToolDomains = baseImport(file.getInputStream(), 1, 1, false, ExcelToolDomain.class);
        } catch (Exception e) {
            LOGGER.error("班组考勤信息导入失败:[{}]", e.getMessage(), e);
        }
        if (null == excelToolDomains) {
            return AjaxResult.error("excel班组考勤信息导入失败，信息为空");
        }
        List<List<ExcelToolDomain>> listOfList = Lists.newArrayList();
        excelToolDomains.stream().collect(Collectors.groupingBy(ExcelToolDomain::getIdCard, Collectors.toList()))
                .forEach((idCard, list) -> {
                    listOfList.add(list);
                });
        String errName = null;
        for (List<ExcelToolDomain> toolDomains : listOfList) {
            if (toolDomains.size() > 1) {
                errName = toolDomains.get(0).getWorkerName();
                break;
            }
        }
        if (StringUtils.isNotBlank(errName)) {
            return AjaxResult.error(errName.concat("信息重复,请核对"));
        }


        excelService.saveWorkerCompanyInfo(excelToolDomains);

        //获取班组考勤信息


        //对比
        //保存到汇总的考勤表
        return AjaxResult.success();
    }



    @GetMapping("/getAttendanceCompany")
    public TableDataInfo getAttendanceCompany(ExcelToolDomain excelToolDomains) {
        startPage();
        List<ExcelToolDomain> workerInfo = excelService.getAttendanceCompany(excelToolDomains);
        return getDataTable(workerInfo);
    }

    /**
     * 导出员工考勤
     *
     * @param excelToolDomains
     * @return com.ruoyi.common.core.domain.AjaxResult
     * @author 刘松山
     * @date 2021/9/10 19:28
     */
    @GetMapping("/attendanceExport")
    public AjaxResult attendanceExport(ExcelToolDomain excelToolDomains) {
        List<ExcelToolDomain> orderList = excelService.getAttendanceGroup(excelToolDomains);
        if (orderList.isEmpty()) {
            return AjaxResult.error("需要导出的数据为空");
        }
        for (ExcelToolDomain e : orderList) {
            if (e.getAttendanceFlag() == 0 || e.getCompanyName() == null) {
                return AjaxResult.error("需要导出的数据存在考勤状态异常，不能导出");
            }
        }
        ExcelUtil<ExcelToolDomain> util = new ExcelUtil<ExcelToolDomain>(ExcelToolDomain.class);
        return util.exportExcel(orderList, "员工考勤数据");
//        //再次分组以渠道商商分组
//        List<List<ExcelToolDomain>> companyOfList = Lists.newArrayList();
//        orderList.stream().collect(Collectors.groupingBy(ExcelToolDomain::getCompanyName, Collectors.toList()))
//                .forEach((companyName, companyList) -> {
//                    companyOfList.add(companyList);
//                });

        //最终结果数据集 companyOfList
        //导出多sheet excel
//        List<Map<String, Object>> sheetsList = Lists.newArrayList();
//        ExportParams deptExportParams = null;
//        Map<String, Object> deptExportMap = null;
//        for (List<ExcelToolDomain> ExcelToolDomains : companyOfList) {
//            deptExportParams = new ExportParams();
//            // 设置sheet得名称
//            deptExportParams.setSheetName(ExcelToolDomains.get(0).getCompanyName());
//            deptExportParams.setTitle(ExcelToolDomains.get(0).getCompanyName().concat(TITLE));
//            short hight = 20;
//            deptExportParams.setTitleHeight(hight);
//            // 创建sheet1使用得map
//            deptExportMap = Maps.newHashMap();
//            // title的参数为ExportParams类型，目前仅仅在ExportParams中设置了sheetName
//            deptExportMap.put("title", deptExportParams);
//            // 模版导出对应得实体类型
//            deptExportMap.put("entity", ExcelToolDomain.class);
//            // sheet中要填充得数据
//            deptExportMap.put("data", ExcelToolDomains);
//            sheetsList.add(deptExportMap);
//        }
//        Workbook workBook = ExcelExportUtil.exportExcel(sheetsList, ExcelType.HSSF);
//        String fileName = TITLE.concat("_") + new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()).toString() + ".xlsx";
//        OutputStream out = null;
//        try {
//            out = new FileOutputStream(getAbsoluteFile(fileName));
//            workBook.write(out);
//            return AjaxResult.success(fileName);
//        } catch (Exception e) {
//            LOGGER.error("excel输出错误信息:[{}]", e.getCause(), e);
//            AjaxResult.error();
//        } finally {
//            IOUtils.closeQuietly(workBook);
//            IOUtils.closeQuietly(out);
//        }
//        return AjaxResult.error();

    }
}
